/**
 * 设置样式
 */
function setStyle(element: HTMLElement, obj: any) {
  Object.assign(element.style, obj)
}

/**
 * 设置data-属性
 * @param element
 * @param item
 */
function setDataAttribute(element: HTMLElement, item: any, dataAttr: string[]) {
  for (const key of dataAttr) {
    const val = item[key]
    element.dataset[key] = key === 'format_option' ? JSON.stringify(val || {}) : val
  }
}

/**
 * 创建外部容器
 */
function createContainer(item: any) {
  const div = document.createElement('div')
  div.classList.add('vdr-container')
  div.classList.add('vdr')
  setDataAttribute(div, item, ['binding'])
  setStyle(div, {
    width: `${item.w}px`,
    height: `${item.h}px`,
    left: `${item.x}px`,
    top: `${item.y}px`,
  })
  const printElement = document.createElement('div')
  printElement.classList.add('print-element')
  console.log('item', item)
  if (item.type === 'table' || item.type === 'customTable') {
    setStyle(printElement, {
      display: 'flex',
      width: `${item.w}px`,
      height: `${item.h}px`,
      fontSize: `${item.fontSize ?? 14}px`,
    })
    if (!item.noBorder) {
      div.classList.add('no-border')
    }
  } else {
    setStyle(printElement, {
      display: 'flex',
      width: `${item.w}px`,
      height: `${item.h}px`,
      fontSize: `${item.fontSize ?? 14}px`,
      borderWidth: `${item.borderWidth || 1}px`,
      borderStyle: item.borderStyle || 'none',
      borderColor: item.borderColor || '#000',
      justifyContent: item.horizontalLine,
      alignItems: item.verticalLine,
      fontWeight: item.isBold ? 'bold' : 'normal',
      textDecoration: item.isUnderline ? 'underline' : 'none',
      fontStyle: item.isItalic ? 'italic' : 'normal',
    })
  }
  setDataAttribute(printElement, item, ['type', 'binding', 'format_option', 'value'])
  const inlineFlex = document.createElement('div')
  inlineFlex.classList.add('inline-flex')
  return {
    div,
    printElement,
    inlineFlex,
  }
}

/**
 * 创建线条
 */
function createLine(item: any) {
  item.horizontalLine = item.horizontalLine || 'center'
  item.verticalLine = item.verticalLine || 'center'
  const { div, printElement } = createContainer(item)
  setStyle(div, {
    transform: `rotate(${item.value || 0}deg)`,
  })
  setDataAttribute(printElement, item, ['label', 'placeholder', 'preview'])
  const line = document.createElement('div')
  setStyle(line, {
    width: `${item.w}px`,
    height: `${item.borderWidth}px`,
    borderStyle: item.borderStyle,
    borderWidth: `${item.borderWidth}px`,
    borderColor: '#000',
  })
  printElement.appendChild(line)
  div.appendChild(printElement)
  return div
}
/**
 * 创建图片
 */
function createImage(item: any) {
  const { div, printElement, inlineFlex } = createContainer(item)
  inlineFlex.innerHTML = `<img width="${item.w}" height="${item.h}" src="${item.value}"/>`
  printElement.appendChild(inlineFlex)
  div.appendChild(printElement)
  return div
}
/**
 * 创建矩形
 */
function createView(item: any) {
  const { div, printElement } = createContainer(item)
  setDataAttribute(printElement, item, ['label', 'placeholder', 'preview'])
  div.appendChild(printElement)
  return div
}

/**
 * 创建信息
 */
function createInfo(item: any) {
  const { div, printElement, inlineFlex } = createContainer(item)
  setStyle(printElement, {
    borderWidth: item.borderWidth,
    borderStyle: item.borderStyle || 'none',
    borderColor: item.borderColor,
    textAlign: item.textAlign,
  })
  inlineFlex.innerHTML = `<label>${item.label}:</label><span>@${item.label}</span>`
  printElement.appendChild(inlineFlex)
  div.appendChild(printElement)
  return div
}

/**
 * 创建自定义文本
 */
function createCustomText(item: any) {
  item.value = item.value || ''
  const { div, printElement, inlineFlex } = createContainer(item)
  inlineFlex.innerHTML = `<span>${item.value}</span>`
  printElement.appendChild(inlineFlex)
  div.appendChild(printElement)
  return div
}

/**
 * 创建表格
 */
function createTable(item: any) {
  const { div, printElement } = createContainer(item)
  const divTable = document.createElement('div')
  divTable.classList.add('table')
  const divTableContainer = document.createElement('div')
  divTableContainer.classList.add('table-container')
  // 生成表格
  const table = document.createElement('table')
  const colgroup = document.createElement('colgroup')
  const tbody = document.createElement('tbody')
  const w = item.w / item.matrix[0].length
  for (const [index, i] of item.matrix.entries()) {
    if (index === 0) {
      for (const n of i) {
        const col = document.createElement('col')
        setStyle(col, {
          width: `${n.width || w}px`,
        })
        setDataAttribute(col, n, ['label', 'binding'])
        col.dataset.placeholder = n.label
        colgroup.appendChild(col)
      }
    }
    const tr = document.createElement('tr')
    tr.classList.add(i[0].class)
    for (const [nIndex, n] of i.entries()) {
      const td = document.createElement('td')
      setStyle(td, {
        height: '18px'
      })
      td.setAttribute('colspan', n.colspan)
      setDataAttribute(td, n, ['binding'])
      td.dataset.label = n.label || n.dataLabel
      td.innerHTML = `<div class="cell">${n.value}</div>`
      if (index === 0 || index === 1) {
        tr.appendChild(td)
      } else if (index === 2) {
        // 打印本页小计
        if (item.pageSubtotal) {
          tr.appendChild(td)
        }
      } else if (index === 3) {
        // 打印合计
        if (item.grandTotalPrint) {
          if (item.totalAmountInWordsPrint && nIndex === 0) {
            // 打印合计金额大写
            td.dataset.format_type = '金额大写'
            td.innerHTML = `<div class="cell">${n.value}{金额大写}</div>`
          }
          tr.appendChild(td)
        }
      }
    }
    tbody.appendChild(tr)
  }
  table.appendChild(colgroup)
  table.appendChild(tbody)

  divTableContainer.appendChild(table)
  divTable.appendChild(divTableContainer)
  printElement.appendChild(divTable)
  div.appendChild(printElement)
  return div
}
/**
 * 创建自定义表格
 */
function createCustomTable(item: any) {
  const { div, printElement } = createContainer(item)
  let value = []
  try {
    value = JSON.parse(item.value)
  } catch (error) {
    value = []
  }
  if (value.length > 0) {
    const divTable = document.createElement('div')
    divTable.classList.add('table')
    const divTableContainer = document.createElement('div')
    divTableContainer.classList.add('table-container')
    // 生成表格
    const table = document.createElement('table')
    const colgroup = document.createElement('colgroup')
    const tbody = document.createElement('tbody')
    const maxLen = value[0].reduce((a, b) => a + b.colspan, 0)
    const w = item.w / maxLen
    for (const [index, i] of value.entries()) {
      if (index === 0) {
        for (const n of i) {
          for (let index = 0; index < n.colspan; index++) {
            const col = document.createElement('col')
            col.style.width = `${w}px`
            colgroup.appendChild(col)
          }
        }
      }
      const tr = document.createElement('tr')
      for (const n of i) {
        const td = document.createElement('td')
        td.setAttribute('colspan', n.colspan)
        setStyle(td, {
          height: '18px',
          padding: '5px',
          fontWeight: n.isBold ? 'bold' : 'normal',
          textDecoration: n.isUnderline ? 'underline' : 'none',
          fontStyle: n.isItalic ? 'italic' : 'normal',
        })
        n.binding = n.binding || ''
        setDataAttribute(td, n, ['binding'])
        td.dataset.label = n.label || n.dataLabel
        const cell = document.createElement('div')
        cell.classList.add('cell')
        setStyle(cell, {
          justifyContent: item.horizontalLine,
          alignItems: item.verticalLine,
          fontWeight: item.isBold ? 'bold' : 'normal',
          textDecoration: item.isUnderline ? 'underline' : 'none',
          fontStyle: item.isItalic ? 'italic' : 'normal',
        })
        cell.innerHTML = `<span>${n.bindKey || n.value}</span>`
        td.appendChild(cell)
        tr.appendChild(td)
      }
      tbody.appendChild(tr)
    }
    table.appendChild(colgroup)
    table.appendChild(tbody)

    divTableContainer.appendChild(table)
    divTable.appendChild(divTableContainer)
    printElement.appendChild(divTable)
  }
  div.appendChild(printElement)
  return div
}
function jsonToHtml({ paperData: paper, templateData }) {
  let printPaper: HTMLDivElement | null = document.createElement('div')
  printPaper.classList.add('print-paper')
  setStyle(printPaper, {
    position: 'relative',
    width: `${paper.w}mm`,
    height: `${paper.h}mm`,
    padding: `${paper.pagePadding.top}mm`,
    backgroundColor: 'rgb(255, 255, 255)',
    fontSize: '14px',
    overflow: 'hidden'
  })
  const printPaperInner = document.createElement('div')
  printPaperInner.classList.add('print-paper__inner')
  setStyle(printPaperInner, {
    lineHeight: 1,
  })
  for (const item of templateData) {
    let dom = null
    switch (item.type) {
      case 'table':
        for (const [index, i] of item.matrix[0].entries()) {
          i.width = item.columnsDataStyle[index].w
          i.height = item.columnsDataStyle[index].h
        }
        dom = createTable(item)
        break
      case 'customTable':
        dom = createCustomTable(item)
        break
      case 'customText':
      case 'title':
      case 'datetime':
      case 'pagination':
        dom = createCustomText(item)
        break
      case 'view':
        dom = createView(item)
        break
      case 'line':
        dom = createLine(item)
        break
      case 'image':
        dom = createImage(item)
        break
      default:
        // text
        dom = createInfo(item)
        break
    }
    dom && printPaperInner.appendChild(dom)
  }
  // 创建页脚
  const printFooter = document.createElement('div')
  printFooter.classList.add('print-footer')
  setStyle(printFooter, {
    bottom: `${paper.pageFooterHeight * 3.8}px`,
  })
  printPaperInner.appendChild(printFooter)
  printPaper.appendChild(printPaperInner)
  console.log('printPaper.outerHTML', printPaper.outerHTML)
  // document.body.appendChild(printPaper)
  const html = `<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>打印</title>
      <style>@page{margin:0;padding:0;}@media print{@page{padding:0;margin:0;size:auto;}}html,body,#app{height:100%;background:#f0f2f5;}*{-webkit-box-sizing:border-box;box-sizing:border-box;}::-webkit-scrollbar{width:4px;height:5px;}::-webkit-scrollbar-thumb{border-radius:4px;background:rgba(136,150,154,0.4);}::-webkit-scrollbar-thumb:hover{background:rgba(136,150,154,0.6);}.print-paper{margin:0 auto;line-height:1.07145;color:#000 !important;font-size:14pt;page-break-after:auto !important;-webkit-column-break-after:auto !important;-moz-column-break-after:auto !important;break-after:auto !important;font-family:Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;-ms-overflow-style:none;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;overflow:hidden;}img{image-resolution:300dpi;max-width:unset;}img:not([src]),img[src='']{opacity:0;}.print-paper .print-paper__inner{position:relative;width:100%;height:100%;}.print-paper .vdr-container{position:absolute;}.print-paper .print-footer{position:absolute;right:0;bottom:0;left:0;border-width:1px;border-color:#c9c9c9;border-top-style:dashed;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:center;}.print-paper table{border:1px solid #000;border-spacing:0;border-collapse:collapse;empty-cells:show;}.print-paper table td{padding:1px;word-break:break-all;text-align:left;vertical-align:middle;line-height:1;height:18px;border-left:1px solid #000;border-bottom:1px solid #000;text-align:center;}.print-paper table td div{word-break:break-all;}.print-paper table tr{line-height:1;}.print-paper table tr td:first-of-type{border-left:none;}.print-paper table tr.border-left td:first-of-type{border-left:1px solid #000;}.print-paper table .row-total td{border-bottom:none;}.no-border,.no-border table,.no-border td,.no-border th{border-color:transparent !important;}.print-paper table .row-total td[data-label='合计'],.print-paper table .row-subtotal td[data-label='本页小计']{text-align:left;}.print-paper .print-element{display:-webkit-box;display:-ms-flexbox;display:flex;word-break:break-all;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;overflow:visible;}.print-paper .print-element[data-type='text']{display:-webkit-box;display:-ms-flexbox;display:flex;white-space:pre-wrap;word-break:break-all;}.print-paper .print-element[data-type='text'] .inline-flex,.print-paper .print-element[data-type='table'] .inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;}.print-paper .print-element[data-type='text'] .inline-flex > label,.print-paper .print-element[data-type='table'] .inline-flex > label{-webkit-box-flex:0;-ms-flex:none;flex:none;white-space:pre-wrap;}.print-paper .print-element[data-type='text'] .inline-flex > span,.print-paper .print-element[data-type='table'] .inline-flex > span{word-break:break-word;}</style>
    </head>

    <body style="page-break-after: always;background: #d8dbe3;">
      ${printPaper.outerHTML}
    </body>

    </html>`
  printPaper = null
  return html
}
export default jsonToHtml
